package com.cardgame.dao;

import com.cardgame.model.level.Level;
import com.cardgame.model.level.LevelInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Repository;
import jakarta.annotation.PostConstruct;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
public class LevelDao implements ILevelDao {
    private final Map<Integer, LevelInfo> levelCache = new HashMap<>();
    private final ObjectMapper objectMapper = new ObjectMapper();
    private static final String LEVEL_FILE_PATH = "data/Level.json";

    public LevelDao() {
        configureObjectMapper();
        init();
//        System.out.println("Level: "+getLevelById(1));
    }

    private void configureObjectMapper() {
        objectMapper.registerSubtypes(Level.class);

    }

    @PostConstruct
    public void init() {
        try {
            File file = new File(LEVEL_FILE_PATH);
            if (!file.exists()) {
                createDefaultLevelData();
            } else {
                List<Map<String, Object>> levels = objectMapper.readValue(file, List.class);

                for (Map<String, Object> levelMap : levels) {
                    LevelInfo level = LevelInfo.valueOf(levelMap);
                    levelCache.put(level.getLevelNumber(), level);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            createDefaultLevelData();
        }
    }

    private void createDefaultLevelData() {
        try {
            File file = new File(LEVEL_FILE_PATH);
            file.getParentFile().mkdirs();

            List<Map<String, Object>> levels = new ArrayList<>();

            // 第一关：新手教程
            Map<String, Object> level1 = new HashMap<>();
            level1.put("levelNumber", 1);
            level1.put("name", "新手教程");
            level1.put("description", "学习基本的游戏机制");
            level1.put("enemyDeckId", 1);
            level1.put("rewardGold", 100);
            level1.put("rewardExp", 50);
            level1.put("backgroundImage", "images/level1_bg.png");
            level1.put("bossImage", "images/level1_boss.png");
            levels.add(level1);

            // 第二关：森林探索
            Map<String, Object> level2 = new HashMap<>();
            level2.put("levelNumber", 2);
            level2.put("name", "森林探索");
            level2.put("description", "在神秘的森林中寻找宝藏");
            level2.put("enemyDeckId", 2);
            level2.put("rewardGold", 200);
            level2.put("rewardExp", 100);
            level2.put("backgroundImage", "images/level2_bg.png");
            level2.put("bossImage", "images/level2_boss.png");
            levels.add(level2);

            // 第三关：城堡守卫
            Map<String, Object> level3 = new HashMap<>();
            level3.put("levelNumber", 3);
            level3.put("name", "城堡守卫");
            level3.put("description", "挑战城堡的守卫者");
            level3.put("enemyDeckId", 3);
            level3.put("rewardGold", 300);
            level3.put("rewardExp", 150);
            level3.put("backgroundImage", "images/level3_bg.png");
            level3.put("bossImage", "images/level3_boss.png");
            levels.add(level3);

            // 保存到文件
            objectMapper.writeValue(file, levels);

            // 更新缓存
            for (Map<String, Object> levelMap : levels) {
                LevelInfo levelInfo = LevelInfo.valueOf(levelMap);
                levelCache.put(levelInfo.getLevelNumber(), levelInfo);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public LevelInfo getLevelById(int levelNumber) {
        return levelCache.get(levelNumber);
    }

    @Override
    public List<LevelInfo> getAllLevels() {
        return new ArrayList<>(levelCache.values());
    }

    @Override
    public int getCurrentProgress() {
        // 获取已解锁的最高关卡号
        return levelCache.keySet().stream()
                .mapToInt(Integer::intValue)
                .max()
                .orElse(0);
    }
} 